<?php
/***********************************************************************
 * @package    IvanEngine
 * @subpackage Core
 * @author     Ivan <ivanzx@msn.com>
 * @created    2010-05-13
 ***********************************************************************/
if(defined("IVANENGINE_CORE_SINGLETON"))
	die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_CORE_SINGLETON", true);

require_once (dirname(__FILE__).'/Object.php');
require_once (dirname(__FILE__).'/STL/Map.php');
require_once (dirname(__FILE__).'/Exception/Exception.php');
require_once (dirname(__FILE__).'/IO/Log.php');

abstract class CSingleton extends CObject 
{
    static protected $m_isSingletonNew  = false;
    static protected $m_singletonMap    = null;
	public function __construct()
	{
		parent::__construct();
        if( self::$m_isSingletonNew == false )
        {
            throw new CException(get_class($this)." class is singleton object, ".
                "you can only use ".get_class($this)."::Get() to get it.");
        }
        if( self::$m_singletonMap == null )
        {
            self::$m_singletonMap   = new CMap();
        }
        self::$m_isSingletonNew = false;
        self::$m_singletonMap->Add(get_class($this), $this);
	}
	
	public function __destruct()
	{
		parent::__destruct();
	}
    
    abstract static public function Get();
    
    static protected function StartSingleton()
    {
        self::$m_isSingletonNew = true;
    }
    
    static protected function EndSingleton()
    {
        if( self::$m_isSingletonNew == true )
        {
            throw new CException("The class is singleton object, ".
                "singleton class must invoke parent::__contruct() in construct function.");
        }
    }
    
    static public function ReleaseAllSingleton()
    {
        self::$m_singletonMap->Clear();
    }
}

?>